///
/// @file GlobalVariable.h
/// @brief 全局变量描述类
///
/// @author zenglj (zenglj@live.com)
/// @version 1.0
/// @date 2024-09-29
///
/// @copyright Copyright (c) 2024
///
/// @par 修改日志:
/// <table>
/// <tr><th>Date       <th>Version <th>Author  <th>Description
/// <tr><td>2024-09-29 <td>1.0     <td>zenglj  <td>新建
/// </table>
///
#pragma once

#include "GlobalValue.h"
#include "IRConstant.h"
#include "ConstantArray.h"
///
/// @brief 全局变量，寻址时通过符号名或变量名来寻址
///
class GlobalVariable : public GlobalValue {

public:
    ///
    /// @brief 构建全局变量，默认对齐为4字节
    /// @param _type 类型
    /// @param _name 名字
    /// @param _initializer 初始化值
    ///
    explicit GlobalVariable(Type * _type, std::string _name, Constant * _initializer = nullptr)
        : GlobalValue(_type, _name), initializer(_initializer)
    {
        // 设置对齐大小
        setAlignment(4);
        // 如果有初始化值且不是全零，则不在BSS段
        if (_initializer)
            inBSSSection = false;
    }

    ///
    /// @brief  检查是否是全局变量
    /// @return true 是全局变量
    /// @return false 不是全局变量
    ///
    [[nodiscard]] bool isGlobalVarible() const override
    {
        return true;
    }

    ///
    /// @brief 是否属于BSS段的变量，即未初始化过的变量，或者初值都为0的变量
    /// @return true
    /// @return false
    ///
    [[nodiscard]] bool isInBSSSection() const
    {
        return this->inBSSSection;
    }

    ///
    /// @brief 取得变量所在的作用域层级
    /// @return int32_t 层级
    ///
    int32_t getScopeLevel() override
    {
        return 0;
    }

    ///
    /// @brief 对该Value进行Load用的寄存器编号
    /// @return int32_t 寄存器编号
    ///
    int32_t getLoadRegId() override
    {
        return this->loadRegNo;
    }

    bool getMemoryAddr(int32_t * regId, int64_t * offset) override
    {
        // 全局变量返回 true，并设置基址寄存器和偏移
        // if (regId) {
        //    *regId = this->loadRegNo;
        //}
        // if (offset) {
        //    *offset = this->offset;
        //}
        return true;
    }

    ///
    /// @brief 对该Value进行Load用的寄存器编号
    /// @return int32_t 寄存器编号
    ///
    void setLoadRegId(int32_t regId) override
    {
        this->loadRegNo = regId;
    }

    ///
    /// @brief 设置初始化值
    /// @param init 初始化值
    ///
    void setInitializer(Constant * init)
    {
        initializer = init;
        if (init)
            inBSSSection = false;
    }

    ///
    /// @brief 获取初始化值
    /// @return Constant* 初始化值
    ///
    Constant * getInitializer() const
    {
        return initializer;
    }

    ///
    /// @brief 判断是否有初始化值
    ///
    bool hasInitValue() const
    {
        return initializer != nullptr;
    }

    ///
    /// @brief 获取int类型的初始化值（仅适用于int类型全局变量）
    ///
    int getInitIntValue() const
    {
        if (initializer) {
            if (auto ci = dynamic_cast<Constant *>(initializer)) {
                return ci->getVal();
            }
        }
        return 0;
    }

    ///
    /// @brief Declare指令IR显示
    /// @param str
    ///
    void toDeclareString(std::string & str)
    {
        str = "declare " + getType()->toString() + " " + getIRName();
    }

    ///
    /// @brief 输出LLVM标准全局变量定义
    /// @param str
    ///
void toDefineString(std::string & str)
{
    str = getIRName();
    str += " = global ";
    str += getType()->toString();
    str += " ";
    
    ConstantArray* CA = dynamic_cast<ConstantArray*>(initializer);

    if (initializer) {
        // 使用 Constant 派生类的 toString 输出具体内容，如 ConstantArray
        if(CA){
            str += CA->toString();
        }else{
            str += initializer->getIRName();
        }
    } else {
        str += "zeroinitializer";
    }

    str += ", align " + std::to_string(getAlignment());
}


private:
    ///
    /// @brief 变量加载到寄存器中时对应的寄存器编号
    ///
    int32_t loadRegNo = -1;

    ///
    /// @brief 默认全局变量在BSS段，没有初始化，或者即使初始化过，但都值都为0
    ///
    bool inBSSSection = true;

    ///
    /// @brief 初始化值
    ///
    Constant * initializer = nullptr;
};
